package com.ittao.taopicture.domain.space.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ittao.taopicture.application.service.PictureApplicationService;
import com.ittao.taopicture.domain.picture.entity.Picture;
import com.ittao.taopicture.domain.space.entity.Space;
import com.ittao.taopicture.domain.space.repository.SpaceRepository;
import com.ittao.taopicture.domain.space.service.SpaceDomainService;
import com.ittao.taopicture.domain.space.valueobject.SpaceLevelEnum;
import com.ittao.taopicture.domain.user.entity.User;
import com.ittao.taopicture.infrastructure.exception.BusinessException;
import com.ittao.taopicture.infrastructure.exception.ErrorCode;
import com.ittao.taopicture.infrastructure.exception.ThrowUtils;
import com.ittao.taopicture.infrastructure.mapper.SpaceMapper;
import com.ittao.taopicture.interfaces.dto.space.SpaceQueryRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author 86134
 * @description 针对表【space(空间)】的数据库操作Service实现
 * @createDate 2025-07-29 22:22:03
 */
@Service
@Slf4j
public class SpaceDomainServiceImpl implements SpaceDomainService {

    @Resource
    private ApplicationContext applicationContext;

    @Resource
    private SpaceRepository spaceRepository;

    // @Resource
    // @Lazy
    // private DynamicShardingManager dynamicShardingManager;

    /**
     * 生成查询参数
     *
     * @param spaceQueryRequest
     * @return
     */
    @Override
    public QueryWrapper<Space> getQueryWrapper(SpaceQueryRequest spaceQueryRequest) {
        QueryWrapper<Space> queryWrapper = new QueryWrapper<>();
        if (spaceQueryRequest == null) {
            return queryWrapper;
        }
        // 从对象中取值
        Long id = spaceQueryRequest.getId();
        Long userId = spaceQueryRequest.getUserId();
        String spaceName = spaceQueryRequest.getSpaceName();
        Integer spaceLevel = spaceQueryRequest.getSpaceLevel();
        Integer spaceType = spaceQueryRequest.getSpaceType();
        String sortField = spaceQueryRequest.getSortField();
        String sortOrder = spaceQueryRequest.getSortOrder();
        // 设置查询条件
        queryWrapper.eq(ObjUtil.isNotEmpty(id), "id", id);
        queryWrapper.eq(ObjUtil.isNotEmpty(userId), "userId", userId);
        queryWrapper.like(StrUtil.isNotBlank(spaceName), "spaceName", spaceName);
        queryWrapper.eq(ObjUtil.isNotEmpty(spaceLevel), "spaceLevel", spaceLevel);
        queryWrapper.eq(ObjUtil.isNotEmpty(spaceType), "spaceType", spaceType);
        // 排序
        queryWrapper.orderBy(StrUtil.isNotBlank(sortField), "ascend".equalsIgnoreCase(sortOrder), sortField);
        return queryWrapper;
    }

    /**
     * 删除空间
     *
     * @param spaceId   空间ID
     * @param loginUser 登录用户
     * @return 是否删除成功
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean deleteSpace(Long spaceId, User loginUser) {
        // 1. 校验参数
        ThrowUtils.throwIf(spaceId == null || spaceId <= 0, ErrorCode.PARAMS_ERROR, "空间ID不能为空");
        ThrowUtils.throwIf(loginUser == null, ErrorCode.NOT_LOGIN_ERROR);

        // 2. 校验空间是否存在
        Space oldSpace = spaceRepository.getById(spaceId);
        ThrowUtils.throwIf(oldSpace == null, ErrorCode.NOT_FOUND_ERROR, "空间不存在");

        // 3. 校验权限：仅本人或管理员可删除
        this.checkSpaceAuth(loginUser, oldSpace);

        // 4. 延迟获取PictureService，避免循环依赖
        PictureApplicationService pictureApplicationService = applicationContext.getBean(PictureApplicationService.class);

        // 5. 查询空间内的所有图片
        List<Picture> pictureList = pictureApplicationService.lambdaQuery()
                .eq(Picture::getSpaceId, spaceId)
                .list();

        // 6. 删除空间内的所有图片（包括文件存储）
        if (CollUtil.isNotEmpty(pictureList)) {
            for (Picture picture : pictureList) {
                try {
                    pictureApplicationService.deletePicture(picture.getId(), loginUser);
                } catch (Exception e) {
                    // 记录日志但不影响空间删除流程
                    log.error("删除图片失败，图片ID：{}，错误信息：{}", picture.getId(), e.getMessage());
                }
            }
        }

        // 7. 删除空间
        boolean result = spaceRepository.removeById(spaceId);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "删除空间失败");

        return true;
    }

    /**
     * 校验空间权限
     *
     * @param loginUser
     * @param space
     */
    @Override
    public void checkSpaceAuth(User loginUser, Space space) {
        // 仅本人或管理员可编辑
        if (!space.getUserId().equals(loginUser.getId()) && !loginUser.isAdmin()) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "无权限编辑该空间");
        }
    }

    /**
     * 补充空间级别字段信息
     *
     * @param space
     */
    @Override
    public void fillSpaceBySpaceLevel(Space space) {
        SpaceLevelEnum spaceLevelEnum = SpaceLevelEnum.getEnumByValue(space.getSpaceLevel());
        if (spaceLevelEnum != null) {
            long maxSize = spaceLevelEnum.getMaxSize();
            // 如果空间的最大大小为null，则设置为对应等级的最大大小
            if (space.getMaxSize() == null) {
                space.setMaxSize(maxSize);
            }
            long maxCount = spaceLevelEnum.getMaxCount();
            // 如果空间的最大数量为null，则设置为对应等级的最大数量
            if (space.getMaxCount() == null) {
                space.setMaxCount(maxCount);
            }
        }
    }
}
